package com.serge.smartdacha;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.Map;

import android.app.Fragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.SystemClock;
import android.preference.PreferenceManager;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Chronometer;
import android.widget.TextView;
import com.serge.smartdacha.model.Controller;
import com.serge.smartdacha.model.CosmController;
import com.serge.smartdacha.model.FMController;
import com.serge.smartdacha.model.PerimeterController;
import com.serge.smartdacha.model.SmsParser;
import com.serge.smartdacha.model.TRController;

public class MonitorFragment extends Fragment {

    public final static String LOAD_DATE_ACTION = "com.serge.smartdacha.load_data";

    private BroadcastReceiver broadcastReceiver;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        setRetainInstance(true);

        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                initUI();
            }
        };
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.monitor_fragment, null);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.monitor, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public void onPause() {
        super.onPause();
        getActivity().unregisterReceiver(broadcastReceiver);
    }

    @Override
    public void onResume() {
        super.onResume();
        getActivity().registerReceiver(broadcastReceiver, new IntentFilter(LOAD_DATE_ACTION));
        initUI();
    }

    private void initUI() {
        ViewGroup trMonitorsLayout = (ViewGroup) getView().findViewById(R.id.trMonitorsLayout);
        trMonitorsLayout.removeAllViews();

        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());

        long lastSmsTs = preferences.getLong(MainActivity.PREF_LATEST_SMS_TS, 0);
        if (lastSmsTs != 0) {
            Date ts = new Date(lastSmsTs);
            TextView tvLastSmsTs = (TextView) getView().findViewById(R.id.tvLastSmsTs);
            tvLastSmsTs.setText(DateFormat.getMediumDateFormat(getActivity()).format(ts) + " " +
                                DateFormat.getTimeFormat(getActivity()).format(ts));

        }

        String sms = preferences.getString(MainActivity.PREF_LATEST_SMS_BODY, null);
        if (sms != null) {

            stopChronometer();

            LayoutInflater inflater = getActivity().getLayoutInflater();

            PerimeterController perimeterController = null;

            Map<String, Controller> map = new SmsParser().parse(sms);
            for (Controller controller : map.values()) {
                if (controller instanceof TRController) {
                    TRController trController = (TRController) controller;
                    String id = trController.getId();

                    View itemView = inflater.inflate(R.layout.trmonitor_item, trMonitorsLayout, false);

                    TextView tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
                    String title = preferences.getString(id + "_title", id);
                    tvTitle.setText(title);

                    TextView tvTemperature = (TextView) itemView.findViewById(R.id.tvTemperature);
                    tvTemperature.setText(trController.getTemperature() + " C");
                    tvTemperature.setOnClickListener(new OpenGraphHandler(getActivity(), id + "_feed", "T", "Температура"));

                    TextView tvMonitorMinTemp = (TextView) itemView.findViewById(R.id.tvMonitorMinTemp);
                    if(trController.getMinTemperature() <= 0) {
                        tvMonitorMinTemp.setText("");
                    }   else {
                        tvMonitorMinTemp.setText(trController.getMinTemperature() + " C");
                    }

                    TextView tvHumidity = (TextView) itemView.findViewById(R.id.tvHumidity);
                    tvHumidity.setText(trController.getHumidity() + " %");
                    tvHumidity.setOnClickListener(new OpenGraphHandler(getActivity(), id + "_feed", "H", "Влажноть"));

                    TextView tvRelay = (TextView) itemView.findViewById(R.id.tvRelay);
                    tvRelay.setText(trController.isRelayOn() ? "Вкл." : "Выкл.");
                    tvRelay.setBackgroundColor(getResources().getColor(trController.isRelayOn() ? R.color.relay_on_bg : R.color.relay_off_bg));
                    tvRelay.setTextColor(getResources().getColor(trController.isRelayOn() ? R.color.relay_on_fg : R.color.relay_off_fg));
                    tvRelay.setOnClickListener(new OpenGraphHandler(getActivity(), id + "_feed", "R", "Батарея"));

                    TextView tvSensorError = (TextView) itemView.findViewById(R.id.tvSensorError);
                    if(trController.getErrorCount() > 0) {
                        tvSensorError.setText(getResources().getString(R.string.sensor_errors, trController.getErrorCount()));
                    } else {
                        tvSensorError.setText("");
                    }

                    trMonitorsLayout.addView(itemView);
                } else if (controller instanceof CosmController) {
                    CosmController cosmController = (CosmController) controller;

                    TextView tvCosmInterval = (TextView) getView().findViewById(R.id.tvCosmIntervalMonitor);
                    tvCosmInterval.setText(cosmController.toText(getResources(), cosmController.getInterval()));
                } else if (controller instanceof PerimeterController) {
                    perimeterController = (PerimeterController) controller;

                    TextView tvPerimeter = (TextView) getView().findViewById(R.id.tvPerimeter);
                    if (perimeterController.getAlarm()) {
                        tvPerimeter.setTextColor(getResources().getColor(R.color.alarm_on_fg));
                        tvPerimeter.setText(getResources().getString(R.string.alarm_on));
                    } else {
                        tvPerimeter.setTextColor(getResources().getColor(R.color.value_fg));
                        tvPerimeter.setText(perimeterController.getActive() ?
                                            getResources().getString(R.string.perimeter_on) :
                                            getResources().getString(R.string.perimeter_off));
                    }
                } else if (controller instanceof FMController) {
                    FMController fmController = (FMController) controller;

                    TextView tvFreeMemory = (TextView) getView().findViewById(R.id.tvFreeMemory);
                    tvFreeMemory.setText(String.valueOf(fmController.getFreeMemory()));
                }
            }
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.miRefresh:
                sendSms();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    private void sendSms() {
        ((MainActivity) getActivity()).sendSmsCommand("get");
        startChronometer();
    }

    private void startChronometer() {
        View controlChronometerLayout = getView().findViewById(R.id.monitorChronometerLayout);
        controlChronometerLayout.setVisibility(View.VISIBLE);
        Chronometer chronometer = (Chronometer) getView().findViewById(R.id.monitorChronometer);
        chronometer.setBase(SystemClock.elapsedRealtime());
        chronometer.start();
    }

    private void stopChronometer() {
        View controlChronometerLayout = getView().findViewById(R.id.monitorChronometerLayout);
        controlChronometerLayout.setVisibility(View.GONE);
        Chronometer chronometer = (Chronometer) getView().findViewById(R.id.monitorChronometer);
        chronometer.stop();
    }

    private static class OpenGraphHandler implements View.OnClickListener {

        private String feedKey;

        private String stream;

        private Context context;

        private String title;

        private OpenGraphHandler(Context context, String feedKey, String stream, String title) {
            this.title = title;
            this.context = context;
            this.stream = stream;
            this.feedKey = feedKey;
        }

        @Override
        public void onClick(View view) {
            SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(view.getContext());
            String feed = sharedPrefs.getString(feedKey, null);
            String url = "http://api.cosm.com/v2/feeds/" + feed + "/datastreams/" + stream +
                         ".png?duration=1day";
            try {
                url += "&title=" + URLEncoder.encode(title, "UTF-8");
            } catch (UnsupportedEncodingException e) {
                Log.e(MonitorFragment.class.getSimpleName(), e.getMessage(), e);
            }
            url += "&show_axis_labels=true&detailed_grid=true&timezone=+4";
            Intent k = new Intent(context, GraphActivity.class);
            k.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
            k.putExtra(GraphActivity.GRAPH_URL, url);
            view.getContext().startActivity(k);
        }
    }
}
